package number


import "math"


// 整数整除，向无穷大取整
func IFloorDiv(a, b int64) int64 {

	if (a > 0 && b > 0) || (a < 0 && b < 0) || (a % b == 0) {
		return a / b
	} else {
		return a/b - 1
	}
}


// 浮点数整除，向无穷大取整
func FFloorDiv(a, b float64) float64 {

	return math.Floor(a / b)
}


// 整数取模
func IMod(a, b int64) int64 {

	return a - IFloorDiv(a, b) * b
}


// 浮点数取模
func FMod(a, b float64) float64 {

	return a - FFloorDiv(a, b) * b
}


// 左移
func ShiftLeft(a, n int64) int64 {

	if n >= 0 {
		return a << uint64(n)
	} else {
		return ShiftRight(a, -n)
	}
}


// 右移
// Go语言里位移运算符右边的操作数只能是无符号整数
// 所以在第一个分支里对位移位数进行了类型转换
// Go语言里，如果右移运算符的左操作数是有符号整数，那么进行的是有符号右移(空缺补1)
// 但是我们期望的是无符号右移
// 所以在第一个分支里需要先将做操作数转换成无符号整数在执行右移操作
// 然后再将结果转换回有符号整数
func ShiftRight(a, n int64) int64 {

	if n >= 0 {
		return int64(uint64(a) >> uint64(n))
	} else {
		return ShiftLeft(a, -n)
	}
}


// 浮点数转换为整数
// 如果浮点数的小数部分为0，且整数部分没有超出Lua整数能够表示的范围，则转换成功
// 否则，转换失败
func FloatToInteger(f float64) (int64, bool) {

	i := int64(f)

	return i, float64(i) == f
}